local famBags = LibStub('AceAddon-3.0'):GetAddon('famBags')

famBags.Compatibility = {}

-- :::::::::::: LOCALS ::::::::::::: -------------------------------------------------------------------------

local L = famBags.L

local function npairs(t)
   local a = {}
      for n in pairs(t) do table.insert(a, n) end
      table.sort(a)
      local i = 0      -- iterator variable
      local iter = function ()   -- iterator function
         i = i + 1
         if a[i] == nil then return nil
         else return a[i], t[a[i]]
         end
      end
   return iter
end

local function get_value_index(arr, value, field)
   for i,v in pairs(arr) do
      if field then
         if v[field] == value then return i end
      else
         if v == value then return i end
      end
   end
   return nil
end

-- :::::::::::: famBags.Compatibility ::::::::::::: -------------------------------------------------------------------------

function famBags.Compatibility:ConvertCategories()
   local db1 = famBags.db.profile.categories
   local db2 = famBags.db.profile.categoriesV2
   local dbs = famBags.db.profile.sections

   local oldcategories = {}
   for n in npairs(db1) do
      table.insert(oldcategories, n)
   end

   local count = 0
   local symbolIndex
   local oldcat, newcat, newcrit
   local index
   for _,catname in pairs(oldcategories) do
      oldcat = db1[catname]
      newcat = {
         category = strsub(catname, 4),
         container = 'all',
         logic = '',
         criterias = {},
      }
      symbolIndex = 1
      if oldcat.Types and next(oldcat.Types) then
         for typename, subtypes in pairs(oldcat.Types) do
            if symbolIndex > #famBags.Symbols then break end
            index = get_value_index(famBags.Criterias[FAMBAGSCRITERIA_TYPESUBTYPE].options, typename)
            if index then
               newcrit = {
                  index = FAMBAGSCRITERIA_TYPESUBTYPE,
                  type = index,
                  symbol = famBags.Symbols[symbolIndex],
                  options = {},
               }
               newcat.logic = newcat.logic..((newcat.logic ~= '') and ' or ' or '')..newcrit.symbol
               if subtypes then
                  if not next(subtypes) or rawget(subtypes, L['.: All :.']) then
                     newcrit.options[0] = 1
                  elseif next(subtypes) then
                     for subtypename, v in pairs(subtypes) do
                        index = get_value_index(famBags.Subtypes[newcrit.type], subtypename)
                        if index then
                           newcrit.options[index] = 1
                        end
                     end
                  end
               end
               table.insert(newcat.criterias, newcrit)
               symbolIndex = symbolIndex + 1
            end
         end
      end
      if oldcat.Criterias and next(oldcat.Criterias) then
         if #newcat.logic > 1 then
            newcat.logic = '('..newcat.logic..')'
         end
         for _, oldcriteria in ipairs(oldcat.Criterias) do
            if symbolIndex > #famBags.Symbols then break end
            index = get_value_index(famBags.Criterias, oldcriteria.name, 'name')
            if index then
               newcrit = {
                  index = index,
                  symbol = famBags.Symbols[symbolIndex],
               }
               newcat.logic = newcat.logic..((newcat.logic ~= '') and ' '..strlower(oldcriteria.operator)..' ' or '')..newcrit.symbol
               if oldcriteria.criterias then
                  if famBags.Criterias[newcrit.index].valueType then
                     newcrit.value = oldcriteria.value
                     local compname = next(oldcriteria.criterias)
                     newcrit.comparer = get_value_index(famBags.Criterias[newcrit.index].options, compname)
                  else
                     newcrit.options = {}
                     if not next(oldcriteria.criterias) or rawget(oldcriteria.criterias, L['.: All :.']) then
                        newcrit.options[(famBags.Criterias[index].stringKeys) and '0' or 0] = 1
                     elseif next(oldcriteria.criterias) then
                        for critoptionname, v in pairs(oldcriteria.criterias) do
                           -- Special treatments
                           if newcrit.index == FAMBAGSCRITERIA_QUALITY then
                              critoptionname = string.gsub(critoptionname, '^%d\.', '')
                           end
                           index = (famBags.Criterias[newcrit.index].stringKeys)
                                       and critoptionname
                                       or  get_value_index(famBags.Criterias[newcrit.index].options, critoptionname)
                           if index then
                              newcrit.options[index] = 1
                           end
                        end
                     end
                  end
               end
               table.insert(newcat.criterias, newcrit)
               symbolIndex = symbolIndex + 1
            end
         end
      end
      table.insert(db2, newcat)
      count = count + 1
      if dbs[catname] then
         dbs[newcat.category], dbs[catname] = dbs[catname], nil
      end
   end
   return count
end

